package server.gui;

import java.awt.event.ActionEvent;

import javax.swing.JOptionPane;

import server.LogException;
import server.ServerMonitor;
import server.Statistics;

/**
 * <h1>Class ServerMainView</h1>
 * 
 * Displays the main window to observe statistics, errors and control
 * the server.
 *
 * @author Tomas
 * @date March 3 2009
 */
public class ServerMainView extends javax.swing.JFrame{

    /**
	 * Required 
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Server started
	 */
	protected boolean started = false;
	
	/**
	 * Instance of the server monitor.
	 */
	protected ServerMonitor server = null;
	
	/**
	 * Thread to refresh the screen.
	 */
	protected ScreenRefresh refresh = null;
	
	/**
	 * Chart for the number of sessions
	 */
	protected GraphicLineChart sessionsChart = null;
	
	/**
	 * Chart for the number of conversations.
	 */
	protected GraphicLineChart conversationsChart = null;
	
	/**
	 * Chart for the message statistics.
	 */
	protected GraphicLineChart messagesChart = null;
	
	/**
	 * Chart for the file sharing statistics.
	 */
	protected GraphicLineChart filesChart = null;
	
	private javax.swing.JPanel Conversations;
    private javax.swing.JLabel conversationsImage;
    private javax.swing.JMenuItem exceptionsButton;
    private javax.swing.JMenuItem exitButton;
    private javax.swing.JMenuItem graphButton;
    private javax.swing.JPanel graphPanel;
    private javax.swing.JMenuItem historyButton;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JMenuBar menubar;
    private javax.swing.JLabel messagesImage;
    private javax.swing.JLabel fileImage;
    private javax.swing.JPanel fileSharingPanel;
    private javax.swing.JMenuItem onlineUsersButton;
    private javax.swing.JSeparator sep1;
    private javax.swing.JSeparator sep2;
    private javax.swing.JMenu serverMenu;
    private javax.swing.JLabel sessionImage;
    private javax.swing.JPanel sessionsTab;
    private javax.swing.JMenuItem startButton;
    private javax.swing.JLabel statusBar;
    private javax.swing.JMenuItem stopButton;
    private javax.swing.JPanel summaryPanel;
    private javax.swing.JTextArea summaryText;
    private javax.swing.JTabbedPane tabs;
    private javax.swing.JMenu usersMenu;
	
	/**
	 * Initializes the components for the window.
	 */
    public ServerMainView() {
    	server = ServerMonitor.getInstance();
        initComponents();
        sessionsChart = new GraphicLineChart(new String[]{"Session"}, 20, "Sessions", "Time", "#Sessions");
        conversationsChart = new GraphicLineChart(new String[]{"Conversation"}, 20, "Conversations", "Time", "#Conversations");
        messagesChart = new GraphicLineChart(new String[]{"Instant", "Average"}, 20, "Messages", "Time", "Message length");
        filesChart = new GraphicLineChart(new String[]{"File size"}, 20, "File sharing", "Time", "File size");
        this.setLocationRelativeTo(null);
    }

    private void initComponents() {

        summaryPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        summaryText = new javax.swing.JTextArea();
        graphPanel = new javax.swing.JPanel();
        tabs = new javax.swing.JTabbedPane();
        sessionsTab = new javax.swing.JPanel();
        sessionImage = new javax.swing.JLabel();
        Conversations = new javax.swing.JPanel();
        conversationsImage = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        messagesImage = new javax.swing.JLabel();
        fileSharingPanel = new javax.swing.JPanel();
        fileImage = new javax.swing.JLabel();
        statusBar = new javax.swing.JLabel();
        menubar = new javax.swing.JMenuBar();
        serverMenu = new javax.swing.JMenu();
        startButton = new javax.swing.JMenuItem();
        stopButton = new javax.swing.JMenuItem();
        sep1 = new javax.swing.JSeparator();
        exceptionsButton = new javax.swing.JMenuItem();
        historyButton = new javax.swing.JMenuItem();
        sep2 = new javax.swing.JSeparator();
        exitButton = new javax.swing.JMenuItem();
        usersMenu = new javax.swing.JMenu();
        onlineUsersButton = new javax.swing.JMenuItem();
        graphButton = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Parlanchin Server");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        summaryPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Summary"));

        summaryText.setColumns(20);
        summaryText.setEditable(false);
        summaryText.setRows(5);
        jScrollPane1.setViewportView(summaryText);

        javax.swing.GroupLayout summaryPanelLayout = new javax.swing.GroupLayout(summaryPanel);
        summaryPanel.setLayout(summaryPanelLayout);
        summaryPanelLayout.setHorizontalGroup(
            summaryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(summaryPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE)
                .addContainerGap())
        );
        summaryPanelLayout.setVerticalGroup(
            summaryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(summaryPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                .addContainerGap())
        );

        graphPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Graphic"));

        tabs.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));

        sessionsTab.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));

        javax.swing.GroupLayout sessionsTabLayout = new javax.swing.GroupLayout(sessionsTab);
        sessionsTab.setLayout(sessionsTabLayout);
        sessionsTabLayout.setHorizontalGroup(
            sessionsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(sessionsTabLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(sessionImage, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE)
                .addContainerGap())
        );
        sessionsTabLayout.setVerticalGroup(
            sessionsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(sessionsTabLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(sessionImage, javax.swing.GroupLayout.DEFAULT_SIZE, 373, Short.MAX_VALUE)
                .addContainerGap())
        );

        tabs.addTab("Sessions", sessionsTab);

        javax.swing.GroupLayout ConversationsLayout = new javax.swing.GroupLayout(Conversations);
        Conversations.setLayout(ConversationsLayout);
        ConversationsLayout.setHorizontalGroup(
            ConversationsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ConversationsLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(conversationsImage, javax.swing.GroupLayout.DEFAULT_SIZE, 625, Short.MAX_VALUE)
                .addContainerGap())
        );
        ConversationsLayout.setVerticalGroup(
            ConversationsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ConversationsLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(conversationsImage, javax.swing.GroupLayout.DEFAULT_SIZE, 375, Short.MAX_VALUE)
                .addContainerGap())
        );

        tabs.addTab("Conversations", Conversations);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(messagesImage, javax.swing.GroupLayout.DEFAULT_SIZE, 625, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(messagesImage, javax.swing.GroupLayout.DEFAULT_SIZE, 375, Short.MAX_VALUE)
                .addContainerGap())
        );

        tabs.addTab("Messages", jPanel1);

        javax.swing.GroupLayout graphPanelLayout = new javax.swing.GroupLayout(graphPanel);
        graphPanel.setLayout(graphPanelLayout);
        graphPanelLayout.setHorizontalGroup(
            graphPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(graphPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tabs, javax.swing.GroupLayout.DEFAULT_SIZE, 653, Short.MAX_VALUE)
                .addContainerGap())
        );
        graphPanelLayout.setVerticalGroup(
            graphPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, graphPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tabs, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                .addContainerGap())
        );

        javax.swing.GroupLayout fileSharingPanelLayout = new javax.swing.GroupLayout(fileSharingPanel);
        fileSharingPanel.setLayout(fileSharingPanelLayout);
        fileSharingPanelLayout.setHorizontalGroup(
            fileSharingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(fileSharingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(fileImage, javax.swing.GroupLayout.DEFAULT_SIZE, 625, Short.MAX_VALUE)
                .addContainerGap())
        );
        fileSharingPanelLayout.setVerticalGroup(
            fileSharingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(fileSharingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(fileImage, javax.swing.GroupLayout.DEFAULT_SIZE, 375, Short.MAX_VALUE)
                .addContainerGap())
        );

        tabs.addTab("File sharing", fileSharingPanel);
        
        statusBar.setText("Status");

        serverMenu.setText("Server");

        startButton.setText("Start Server");
        startButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startButtonActionPerformed(evt);
            }
        });
        serverMenu.add(startButton);

        stopButton.setText("Stop Server");
        stopButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                stopButtonActionPerformed(evt);
            }
        });
        serverMenu.add(stopButton);
        serverMenu.add(sep1);

        exceptionsButton.setText("Show Exceptions");
        exceptionsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exceptionsButtonActionPerformed(evt);
            }
        });
        serverMenu.add(exceptionsButton);

        historyButton.setText("Show History");
        historyButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                historyButtonActionPerformed(evt);
            }
        });
        serverMenu.add(historyButton);
        serverMenu.add(sep2);

        exitButton.setText("Exit");
        exitButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitButtonActionPerformed(evt);
            }
        });
        serverMenu.add(exitButton);

        menubar.add(serverMenu);

        usersMenu.setText("Users");

        onlineUsersButton.setText("Online Users");
        onlineUsersButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                onlineUsersButtonActionPerformed(evt);
            }
        });
        usersMenu.add(onlineUsersButton);

        graphButton.setText("Relationship Graph");
        graphButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                graphButtonActionPerformed(evt);
            }
        });
        usersMenu.add(graphButton);

        menubar.add(usersMenu);

        setJMenuBar(menubar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(summaryPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(graphPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addComponent(statusBar, javax.swing.GroupLayout.DEFAULT_SIZE, 1124, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(summaryPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(graphPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusBar))
        );

        pack();
    }

    /**
     * Starts the window.
     */
    public static void launch() {
        
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ServerMainView().setVisible(true);
            }
        });
    }

    /**
     * Closes the window.
     * 
     * @param evt
     */
    private void formWindowClosing(java.awt.event.WindowEvent evt) {
        
    	closeWindow();
    	
    }
    
    /**
     * Starts the Server
     * 
     * @param evt
     */
	private void startButtonActionPerformed(ActionEvent evt) {

		if(!started){
			server.startServer();
			started = true;
			statusBar.setText("Server started successfully");
			refresh = new ScreenRefresh(this);
			refresh.start();
		}
		
	}
	
	/**
	 * Stops the server.
	 * 
	 * @param evt
	 */
	private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {

		if(started){
			int response = JOptionPane.showConfirmDialog(this, "Are you sure you want to stop the server?");
			if(response == JOptionPane.OK_OPTION){
				server.stopServer();
				started = false;
				statusBar.setText("Server stopped");
				refresh.finish();
				try{
					refresh.join(500);
				}catch(Exception e){
					LogException.getInstance().logException(e);
				}
			}
		}
    }
	
	/**
	 * Starts the Exception Browser.
	 * 
	 * @param evt
	 */
	private void exceptionsButtonActionPerformed(java.awt.event.ActionEvent evt) {

		ExceptionBrowser window = new ExceptionBrowser();
		
		window.setVisible(true);
		
    }	
	
	/**
	 * Closes the window.
	 * 
	 * @param evt
	 */
	private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {
        
		closeWindow();
		
    }
	
	/**
	 * Closes the window. If the server is started, it asks the user if s/he really wants
	 * to stop it.
	 */
	public void closeWindow(){
		
		if(started){
    		int response = JOptionPane.showConfirmDialog(this, "Are you sure you want to exit?\nThis will stop the server.");
    		if(response == JOptionPane.OK_OPTION){
    			server.stopServer();
    			System.exit(0);
    		}
    	}else{
    		System.exit(0);
    	}
		
	}
	
	/**
	 * Starts the view to show a graph of the users.
	 * 
	 * @param evt
	 */
	private void graphButtonActionPerformed(java.awt.event.ActionEvent evt) {
        
		new ConversationGraph();
		
    }
	
	/**
	 * Starts the view to show historical statistics.
	 * 
	 * @param evt
	 */
	private void historyButtonActionPerformed(java.awt.event.ActionEvent evt) {
        
		HistoryView window = new HistoryView();
		
		window.setVisible(true);
		
    }
	
	/**
	 * Starts the view to show the online users.
	 * 
	 * @param evt
	 */
	private void onlineUsersButtonActionPerformed(java.awt.event.ActionEvent evt) {
        
		OnlineUsers window = new OnlineUsers();
		
		window.setVisible(true);
		
    }
	
	/**
	 * Updates the view with the stats.
	 */
	public void updateStatistics() {

		Statistics stats = Statistics.getInstance();
		String report = stats.toString();
		
		this.sessionsChart.addPoint(0, stats.getNumSessions());
		this.conversationsChart.addPoint(0, stats.getNumConversations());
		this.messagesChart.addPoint(0, stats.getAverageMessageLength());
		this.messagesChart.addPoint(1, stats.getTotalAverageMessageLength());
		this.filesChart.addPoint(0, stats.getFileSize());
		stats.reset();
		
		summaryText.setText(report);
		this.sessionImage.setIcon(this.sessionsChart.getChart(620, 370));
		this.conversationsImage.setIcon(this.conversationsChart.getChart(620, 370));
		this.messagesImage.setIcon(this.messagesChart.getChart(620,370));		
		this.fileImage.setIcon(this.filesChart.getChart(620, 370));
	}
    

}
